﻿using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Edu.Http.Extensions;
using Edu.Http.Proxy;
using Infrastructure.Config.Core.External;
using Infrastructure.ExternalService.Core.FileStorage;
using Infrastructure.ExternalService.Core.Responses;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;

namespace Infrastructure.ExternalService.Core.Imp.FileStorage
{
    public class FileStorageExternal : BaseHttpClient, IFileStorageExternal
    {
        private readonly OrderCenterApiOptions _orderingOptions;
        private readonly string formUrlencoded = "application/x-www-form-urlencoded";

        public FileStorageExternal(IOptions<OrderCenterApiOptions> options
            , HttpClient client, ILoggerFactory loggerFactory)
            : base(client, loggerFactory, options.Value.FileServiceOptions.EndPoint)
        {
            _orderingOptions = options.Value ?? throw new HttpProxyException($"{nameof(FileStorageExternal)}配置获取失败");

            loggerFactory.CreateLogger<FileStorageExternal>();
        }

        /// <summary>
        /// 设置BaseHttpClient的BaseAddress：该值默认是从构造函数传入的，但重写该方法可以改变该值
        /// </summary>
        /// <returns></returns>
        protected override string SetHttpClientBaseAddress()
        {
            return null;
        }

        public async Task FilePersistentConfirmAsync(FilePersistentConfirmRequest request)
        {
            var formStr = ConvertRequestToCommonFormUrlEncode(request);
            var response = await PostJsonAsync<WrapResponse<object>>(url: _orderingOptions.FileServiceOptions.FilePersistentConfirm, jsonStr: formStr, formUrlencoded, headers: null);

            if (response != null && response.Success)
            {
                return;
            }
            throw new HttpProxyException($"{response.Msg}");
        }

        /// <summary>
        /// 上传Excel文件
        /// </summary>
        /// <param name="request"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public async Task<string> FileUploadAsync(FileUploadRequest request, string fileName)
        {
            var formStr = ConvertRequestToCommonFormUrlEncode(request);
            var response = await PostAsync<UploadResponse>($"{_orderingOptions.FileServiceOptions.FileUpload}?{formStr}", fileName);
            if (response.Code.Equals(ClientReturnCode.Success))
            {
                return response?.Data.FilePath;
            }
            throw new HttpProxyException($"{response.Message}");
        }

        /// <summary>
        /// 上传Excel文件
        /// </summary>
        /// <param name="request"></param>
        /// <param name="content"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public async Task<UploadFile> FileUploadAsync(FileUploadRequest request, ByteArrayContent content, string fileName)
        {
            var formStr = ConvertRequestToCommonFormUrlEncode(request);

            var response = await PostAsync<UploadResponse>($"{_orderingOptions.FileServiceOptions.FileUpload}?{formStr}", content, fileName);
            if (response.Code.Equals(ClientReturnCode.Success))
            {
                return response?.Data;
            }

            throw new HttpProxyException($"{response.Message}");
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<Stream> DownloadAsync(DownloadRequest request)
        {
            var strJoin = @"/";

            if (_orderingOptions.FileServiceOptions.EndPoint.EndsWith(@"/") || _orderingOptions.FileServiceOptions.Download.StartsWith(@"/"))
            {
                strJoin = "";
            }

            return await GetStreamAsync($"{_orderingOptions.FileServiceOptions.EndPoint + strJoin + _orderingOptions.FileServiceOptions.Download}?filePath={request.path}");
        }

        /// <summary>
        /// 获取文件下载Token
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<DownloadFileToken> DownloadFileTokenAsync(DownloadFileTokenRequest request)
        {
            var formStr = ConvertRequestToCommonFormUrlEncode(request);
            var response = await PostJsonAsync<WrapResponse<DownloadFileTokenResponse>>(url: _orderingOptions.FileServiceOptions.GetFileDownloadToken, jsonStr: formStr, formUrlencoded, headers: null);

            if (response.Code.Equals(ClientReturnCode.Success))
            {
                return response?.Data.Data.First();
            }
            throw new HttpProxyException($"{response.Msg}");
        }
    }
}
